#include "sessionmanager.h"
#include <QRect>


//----------------------------------------------------------------------------------------
SessionManager::SessionManager (const QString & fileName, Format format, QObject * parent) :
    QSettings (fileName, format, parent)
{
    restore ();
}
//--------------------------------
SessionManager::~SessionManager ()
{
    save ();
}
//-----------------------------------------------------
void SessionManager::addSession (const Session& session)
{
    if (session.isEmpty ()) return;
    m_sessions.insert (session.fileName (), session);
}
//-----------------------------------------------------------------------
void SessionManager::addSession (const QString &fileName,
                                 const int page,
                                 const double scale,
                                 const int contrast,
                                 const qreal zoom1,
                                 const qreal zoom2,
                                 const int removeMargins,
                                 const int rotation,
                                 const QString& text,
                                 const QList<QRect> &greenRects,
                                 const QList<QRect> &redRects,
                                 const QDateTime &dateTime)
{
    if (fileName.isEmpty ()) return;
    Session session (fileName,
                     page,
                     scale,
                     contrast,
                     zoom1,
                     zoom2,
                     removeMargins,
                     rotation,
                     text,
                     greenRects,
                     redRects,
                     dateTime);
    m_sessions.insert (fileName, session);
}
//--------------------------
void SessionManager::save ()
{
    beginGroup ("Global");
    setValue ("CurrentFileName", m_currentFileName);
    endGroup ();

    beginWriteArray ("Sessions");
    int sessionIndex = 0;
    foreach (Session s, m_sessions.values ())
    {
        setArrayIndex (sessionIndex);
        setValue ("FileName", s.fileName ());
        setValue ("PdfPage", s.pdfCurrentPage ());
        setValue ("Scale", s.scale ());
        setValue ("Contrast", s.contrast ());
        setValue ("Zoom1", s.zoom1 ());
        setValue ("Zoom2", s.zoom2 ());
        setValue ("DateTime", s.dateTime ());
        setValue ("RemoveMargins", s.mustCleanImage ());
        setValue ("Rotation", s.rotation ());
        setValue ("Text", s.text ());

        QVariantList tempo;
        foreach (const QRect &r, s.greenRects ()) {
            tempo << r;
        }

        setValue ("GreenRects", tempo);

        tempo.clear ();
        foreach (QRect r, s.redRects ()) {
            tempo << r;
        }

        setValue ("RedRects", tempo);
        sessionIndex++;
    }
    endArray ();
}
//-------------------------------------
void SessionManager::restore ()
{
    clear ();

    beginGroup ("Global");
    setCurrentFileName (value ("CurrentFileName", QString ()).toString ());
    endGroup ();

    const int count1 = beginReadArray ("Sessions");
    for (int sessionIndex = 0 ; sessionIndex != count1 ; ++sessionIndex)
    {
        setArrayIndex (sessionIndex);

        QVariantList greenVar = value ("GreenRects", QVariantList ()).toList ();
        QList<QRect> greenRects;
        foreach (const QVariant &v, greenVar) {
            greenRects << v.toRect ();
        }

        QVariantList redVar = value ("RedRects", QVariantList ()).toList ();
        QList<QRect> redRects;
        foreach (const QVariant &v, redVar) {
            redRects << v.toRect ();
        }

        addSession (value ("FileName", QString ()).toString (),
                    value ("PdfPage", -1).toInt (),
                    value ("Scale", 1.0).toDouble (),
                    value ("Contrast", 127).toInt (),
                    value ("Zoom1", 1.0).toReal (),
                    value ("Zoom2", 1.0).toReal (),
                    value ("RemoveMargins", false).toBool (),
                    value ("Rotation", 0).toInt (),
                    value ("Text", QString ()).toString (),
                    greenRects,
                    redRects,
                    value ("DateTime", QDateTime::currentDateTime ()).toDateTime ());

    }
    endArray (); // Sessions

}
//------------------------------------------------------------------------
Session* SessionManager::sessionOf (const QString &fileName)
// retourner un pointeur sur la session désignée par le nom du fichier
{
    if (fileName.isEmpty ()) return 0;
    QFile file (fileName);
    if (not file.exists ()) return 0;

    if (not m_sessions.contains (fileName))
    {
        qDebug () << "Créer une nouvelle entrée pour" << fileName;
        Session s;
        s.setFileName (fileName);
        addSession (s);
    }

    setCurrentFileName (fileName);
    Session* result = &m_sessions[fileName];
    result->updateDateTime ();
    return result;
}
//------------------------------------------------------------------------------
QStringList SessionManager::recentFileList (const int max) const
{
    QStringList result;
    foreach (const Session& s, m_sessions) {
        result << s.fileName ();
    }

    result = result.mid (0, max);

    return result;
}
//--------------------------
void SessionManager::clear ()
{
    m_currentFileName.clear ();
    m_sessions.clear ();
}

//*********************************** UNDO
void SessionManager::clearUndo ()
{
    qDeleteAll (m_undoStack);
    m_undoStack.clear ();
    emit undoIsPossible (false);
}
//-----------------------------------------
Session * SessionManager::prepareUndo ()
{
    Session* session = new Session;
    m_undoStack.push (session);
    emit undoIsPossible (true);
    return m_undoStack.top ();
}
//-------------------------------------
Session * SessionManager::undoSession ()
{
    Session* result = 0;
    if (canUndo ())
    {
        result = m_undoStack.pop ();
        emit redoIsPossible (true);
    }
    emit undoIsPossible (canUndo ());
    return result;
}
//*********************************** REDO
void SessionManager::clearRedo ()
{
    qDeleteAll (m_redoStack);
    m_redoStack.clear ();
    emit redoIsPossible (false);
}
//---------------------------------------
Session * SessionManager::prepareRedo ()
{
    Session* session = new Session;
    m_redoStack.push (session);
    emit redoIsPossible (true);
    return m_redoStack.top ();
}
//-------------------------------------
Session * SessionManager::redoSession ()
{
    Session* result = 0;
    if (canRedo ())
    {
        result = m_redoStack.pop ();
    }
    emit redoIsPossible (canRedo ());
    return result;
}
